package cn.com.cifi.mars.service.impl;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.cifi.mars.bean.dto.BudgetVersionDto;
import cn.com.cifi.mars.bean.dto.DynamicVersionDto;
import cn.com.cifi.mars.bean.vo.supply.ComfirmBaseValueVO;
import cn.com.cifi.mars.bean.vo.supply.CompareDetailVO;
import cn.com.cifi.mars.bean.vo.supply.SupplyPlanVersionCompareVO;
import cn.com.cifi.mars.bean.vo.supply.YearMonthComfirmVO;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.MonthEnum;
import cn.com.cifi.mars.constant.NumberEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.constant.SalyTypeEnum;
import cn.com.cifi.mars.constant.VersionAttrEnum;
import cn.com.cifi.mars.constant.VersionIdentifyEnum;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.entity.MdmProject;
import cn.com.cifi.mars.entity.SupplyPlanVersion;
import cn.com.cifi.mars.entity.SupplyPlanVersionDetail;
import cn.com.cifi.mars.mapper.mars.ProjectMapper;
import cn.com.cifi.mars.mapper.mars.SupplyPlanVersionDetailMapper;
import cn.com.cifi.mars.mapper.mars.SupplyPlanVersionMapper;
import cn.com.cifi.mars.service.StageService;
import cn.com.cifi.mars.service.SupplyPlanVersionCompareService;
import cn.com.cifi.mars.util.DateUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.NumberUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;

/**
 * <p>
 * 供货计划版本对比 服务实现类
 * </p>
 *
 * @author yyd
 * @since 2019-09-09
 */
@Service
public class SupplyPlanVersionCompareServiceImpl implements SupplyPlanVersionCompareService {
	
	@Autowired
	private SupplyPlanVersionMapper supplyPlanVersionMapper;

	@Autowired
	private SupplyPlanVersionDetailMapper supplyPlanVersionDetailMapper;
	
	@Autowired
	private ProjectMapper projectMapper;
	
	@Autowired
	private StageService stageService;
	
	private static final String firsthalfYearKey  = "firsthalfYear";
	private static final String nexthalfYearKey  = "nexthalfYear";
	@Override
	public List<SupplyPlanVersionCompareVO> selectVersionCompareData(String projectId,String deadline) {
		if(StrUtils.isEmpty(deadline)) {
			deadline = LocalDateTimeUtils.formatTime(LocalDateTime.now(),DateUtils.DATE_JFP_STR);
		}
		String year = deadline.split("-")[0];
		List<SupplyPlanVersionCompareVO> resList = Collections.synchronizedList(new ArrayList<>());
		//获取当前项目下分期
		List<Map<String, Object>> stageList = supplyPlanVersionMapper.selectStageByProjectId(projectId,IsDeleteEnum.NO.getKey());
		if(CollectionUtils.isNotEmpty(stageList)) {
			for(Map<String, Object> map: stageList) {
				String stageId = String.valueOf(map.get("projectf_id"));
				boolean isActiveStage = stageService.isActiveStage(stageId);
				if(!isActiveStage) {
					continue;
				}
				List<List<CompareDetailVO>> compareDataList = Collections.synchronizedList(new ArrayList<>());
				//获取年初最新预算版
				List<SupplyPlanVersionDetail> newsetAllYearBudgetList = supplyPlanVersionDetailMapper.selectNewsetAllYearBudgetList(prepareBudgetParameters(stageId, year,VersionIdentifyEnum.ALL_YEAR.getKey()));
				//获取截止当前日期最新月度动态版
				List<SupplyPlanVersionDetail> newsetDynamicList = supplyPlanVersionDetailMapper.selectNewestDynamicList(prepareDynamicParameters(stageId,deadline));
				
				//================当前年度对比合计  BEGIN===========================================================
				List<CompareDetailVO> newsetAllYearBudgetData = handleData(projectId,newsetAllYearBudgetList,deadline,"","",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> newsetDynamicData =  handleData(projectId,newsetDynamicList,deadline,"","",VersionTypeEunm.DYNAMIC.getKey());
				//================当前年度对比合计  END==============================================================
				
				//================当前年 1月~6月 月度动态版合计BEGIN=====================================================
				List<CompareDetailVO> januaryBudgetData = handleData(projectId,newsetAllYearBudgetList,deadline,MonthEnum.january.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> januaryDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.january.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> februaryBudgetData =handleData(projectId,newsetAllYearBudgetList,deadline,MonthEnum.february.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> februaryDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.february.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> marchBudgetData =handleData(projectId,newsetAllYearBudgetList,deadline,MonthEnum.march.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> marchDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.march.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> aprilBudgetData = handleData(projectId,newsetAllYearBudgetList,deadline,MonthEnum.april.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> aprilDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.april.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> mayBudgetData =handleData(projectId,newsetAllYearBudgetList,deadline,MonthEnum.may.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> mayDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.may.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> juneBudgetData =handleData(projectId,newsetAllYearBudgetList,deadline,MonthEnum.june.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> juneDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.june.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				//================当前年 1月~6月 月度动态版合计  END=======================================================
				
				//================当前年 上半年 半年度动态版合计BEGIN=====================================================
				List<CompareDetailVO> firsthalfYearBudgetData =  handleData(projectId,newsetAllYearBudgetList,deadline,"",firsthalfYearKey,VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> firsthalfYearDynamicData =  handleData(projectId,newsetDynamicList,deadline,"",firsthalfYearKey,VersionTypeEunm.DYNAMIC.getKey());
				//================当前年 上半年 半年度动态版合计BEGIN=====================================================
				
				//获取年中最新预算版
				List<SupplyPlanVersionDetail> newsetMidYearBudgetList = supplyPlanVersionDetailMapper.selectNewsetAllYearBudgetList(prepareBudgetParameters(stageId, year,VersionIdentifyEnum.MID_YEAR.getKey()));
				List<CompareDetailVO> newsetMidYearBudgetData =Collections.synchronizedList(new ArrayList<>());
				if(CollectionUtils.isEmpty(newsetMidYearBudgetList)) {
					newsetMidYearBudgetList = newsetAllYearBudgetList;
					newsetMidYearBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,"",nexthalfYearKey,VersionTypeEunm.BUDGET.getKey());
				}else {
					 newsetMidYearBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,"",nexthalfYearKey,VersionTypeEunm.BUDGET.getKey());
				}
				
				//================当前年 下半年 半年度动态版合计BEGIN=====================================================
				List<CompareDetailVO> nexthalfYearDynamicData =  handleData(projectId,newsetDynamicList,deadline,"",nexthalfYearKey,VersionTypeEunm.DYNAMIC.getKey());
				//================当前年 下半年 半年度动态版合计BEGIN=====================================================
				
				//================当前年 7月~12月 月度动态版合计BEGIN=====================================================
				List<CompareDetailVO> julyBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,MonthEnum.july.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> julyDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.july.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> augustBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,MonthEnum.august.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> augustDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.august.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> septemberBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,MonthEnum.september.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> septemberDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.september.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> octoberBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,MonthEnum.october.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> octoberDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.october.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> novemberBudgetData =  handleData(projectId,newsetMidYearBudgetList,deadline,MonthEnum.november.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> novemberDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.november.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				
				List<CompareDetailVO> decemberBudgetData = handleData(projectId,newsetMidYearBudgetList,deadline,MonthEnum.december.getValue(),"",VersionTypeEunm.BUDGET.getKey());
				List<CompareDetailVO> decemberDynamicData =  handleData(projectId,newsetDynamicList,deadline,MonthEnum.december.getValue(),"",VersionTypeEunm.DYNAMIC.getKey());
				//================当前年 7月~12月 月度动态版合计  END=======================================================
				
				compareDataList.add(newsetAllYearBudgetData);
				compareDataList.add(newsetDynamicData);
				
				compareDataList.add(januaryBudgetData);
				compareDataList.add(januaryDynamicData);
				
				compareDataList.add(februaryBudgetData);
				compareDataList.add(februaryDynamicData);
				
				compareDataList.add(marchBudgetData);
				compareDataList.add(marchDynamicData);
				
				compareDataList.add(aprilBudgetData);
				compareDataList.add(aprilDynamicData);
				
				compareDataList.add(mayBudgetData);
				compareDataList.add(mayDynamicData);
				
				compareDataList.add(juneBudgetData);
				compareDataList.add(juneDynamicData);
				
				compareDataList.add(firsthalfYearBudgetData);
				compareDataList.add(firsthalfYearDynamicData);
				
				compareDataList.add(newsetMidYearBudgetData);
				compareDataList.add(nexthalfYearDynamicData);
				
				compareDataList.add(julyBudgetData);
				compareDataList.add(julyDynamicData);
				
				compareDataList.add(augustBudgetData);
				compareDataList.add(augustDynamicData);
				
				compareDataList.add(septemberBudgetData);
				compareDataList.add(septemberDynamicData);
				
				compareDataList.add(octoberBudgetData);
				compareDataList.add(octoberDynamicData);
				
				compareDataList.add(novemberBudgetData);
				compareDataList.add(novemberDynamicData);
				
				compareDataList.add(decemberBudgetData);
				compareDataList.add(decemberDynamicData);
				
				//合并层级数据
				List<CompareDetailVO> mergeDataList = mergeData(compareDataList);
				
				if(CollectionUtils.isNotEmpty(mergeDataList)) {
					for(CompareDetailVO mergeObj : mergeDataList) {
						SupplyPlanVersionCompareVO vo = new SupplyPlanVersionCompareVO();
						String baseFullPathName = mergeObj.getOrgFullPathName();
						vo.setId(mergeObj.getId());
						vo.setCode(mergeObj.getOrgCode());
						vo.setName(mergeObj.getOrgName());
						vo.setPid(mergeObj.getPid());
						vo.setType(mergeObj.getType());
						vo.setIsParking(mergeObj.getIsParking());
						vo.setBusinessTypeName(mergeObj.getBusinessTypeName());
						vo.setFreeTypeName(mergeObj.getFreeTypeName());
						vo.setProTypeName(mergeObj.getProTypeName());
						//年度
						YearMonthComfirmVO yearValue = vo.getYearValue();
						List<YearMonthComfirmVO> firstMonthlyValue = getMonthData(year,1);
						vo.setFirstMonthlyValue(firstMonthlyValue);
						YearMonthComfirmVO firstHalfYearValue = vo.getFirstHalfYearValue();
						YearMonthComfirmVO secondHalfYearValue = vo.getSecondHalfYearValue();
						List<YearMonthComfirmVO> secondMonthlyValue = getMonthData(year,2);
						vo.setSecondMonthlyValue(secondMonthlyValue);
						//年度
						prepareYearCompareData(newsetAllYearBudgetData,newsetDynamicData,baseFullPathName,yearValue);
						//上半年月度
						prepareMonthlyCompare(januaryBudgetData,januaryDynamicData,baseFullPathName,firstMonthlyValue,MonthEnum.january.getValue());
						prepareMonthlyCompare(februaryBudgetData,februaryDynamicData,baseFullPathName,firstMonthlyValue,MonthEnum.february.getValue());
						prepareMonthlyCompare(marchBudgetData,marchDynamicData,baseFullPathName,firstMonthlyValue,MonthEnum.march.getValue());
						prepareMonthlyCompare(aprilBudgetData,aprilDynamicData,baseFullPathName,firstMonthlyValue,MonthEnum.april.getValue());
						prepareMonthlyCompare(mayBudgetData,mayDynamicData,baseFullPathName,firstMonthlyValue,MonthEnum.may.getValue());
						prepareMonthlyCompare(juneBudgetData,juneDynamicData,baseFullPathName,firstMonthlyValue,MonthEnum.june.getValue());
						//上半年度
						prepareYearCompareData(firsthalfYearBudgetData,firsthalfYearDynamicData,baseFullPathName,firstHalfYearValue);
						//下半年度
						prepareYearCompareData(newsetMidYearBudgetData,nexthalfYearDynamicData,baseFullPathName,secondHalfYearValue);
						//下半年月度
						prepareMonthlyCompare(julyBudgetData,julyDynamicData,baseFullPathName,secondMonthlyValue,MonthEnum.july.getValue());
						prepareMonthlyCompare(augustBudgetData,augustDynamicData,baseFullPathName,secondMonthlyValue,MonthEnum.august.getValue());
						prepareMonthlyCompare(septemberBudgetData,septemberDynamicData,baseFullPathName,secondMonthlyValue,MonthEnum.september.getValue());
						prepareMonthlyCompare(octoberBudgetData,octoberDynamicData,baseFullPathName,secondMonthlyValue,MonthEnum.october.getValue());
						prepareMonthlyCompare(novemberBudgetData,novemberDynamicData,baseFullPathName,secondMonthlyValue,MonthEnum.november.getValue());
						prepareMonthlyCompare(decemberBudgetData,decemberDynamicData,baseFullPathName,secondMonthlyValue,MonthEnum.december.getValue());
						
						resList.add(vo);
					}
				}
			}
		}
		List<SupplyPlanVersionCompareVO> sortList = Collections.synchronizedList(new ArrayList<>());
		//数据汇总
		if(CollectionUtils.isNotEmpty(resList)) {
			collectData(resList,OrgTypeEunm.ORG_GROUP.getKey());
			collectData(resList,OrgTypeEunm.ORG_STAGE.getKey());
			addProjectData(resList,projectId,year);
			collectData(resList,OrgTypeEunm.ORG_PRODUCTF.getKey());
			sortList = dataSort(resList);
		}
		handleAvg(sortList);
		return sortList;
	}
	
	private void handleAvg(List<SupplyPlanVersionCompareVO> resList) {
		for(SupplyPlanVersionCompareVO vo : resList) {
				YearMonthComfirmVO yearValue = vo.getYearValue();
				List<YearMonthComfirmVO> firstMonthlyValue = vo.getFirstMonthlyValue();
				YearMonthComfirmVO firstHalfYearValue = vo.getFirstHalfYearValue();
				YearMonthComfirmVO secondHalfYearValue = vo.getSecondHalfYearValue();
				List<YearMonthComfirmVO> secondMonthlyValue = vo.getSecondMonthlyValue();
				
				yearValue.getBudgetValue().setHouseAvgPrice(NumberUtils.divide(yearValue.getBudgetValue().getHousePrice(), yearValue.getBudgetValue().getSaleArea(), 4));
				yearValue.getBudgetValue().setParkingAvgPrice(NumberUtils.divide(yearValue.getBudgetValue().getParkingPrice(), yearValue.getBudgetValue().getParkingNum()==null?null:new BigDecimal(yearValue.getBudgetValue().getParkingNum()), 4));
				yearValue.getDynamicValue().setHouseAvgPrice(NumberUtils.divide(yearValue.getDynamicValue().getHousePrice(), yearValue.getDynamicValue().getSaleArea(), 4));
				yearValue.getDynamicValue().setParkingAvgPrice(NumberUtils.divide(yearValue.getDynamicValue().getParkingPrice(), yearValue.getDynamicValue().getParkingNum()==null?null:new BigDecimal(yearValue.getDynamicValue().getParkingNum()), 4));
				yearValue.getDifferenceValue().setHouseAvgPrice(NumberUtils.divide(yearValue.getDifferenceValue().getHousePrice(), yearValue.getDifferenceValue().getSaleArea(),4));
				yearValue.getDifferenceValue().setParkingAvgPrice(NumberUtils.divide(yearValue.getDifferenceValue().getParkingPrice(), yearValue.getDifferenceValue().getParkingNum()==null?null:new BigDecimal(yearValue.getDifferenceValue().getParkingNum()),4 ));
			
				for(YearMonthComfirmVO first : firstMonthlyValue) {
					first.getBudgetValue().setHouseAvgPrice(NumberUtils.divide(first.getBudgetValue().getHousePrice(), first.getBudgetValue().getSaleArea(), 4));
					first.getBudgetValue().setParkingAvgPrice(NumberUtils.divide(first.getBudgetValue().getParkingPrice(), first.getBudgetValue().getParkingNum()==null?null:new BigDecimal(first.getBudgetValue().getParkingNum()), 4));
					first.getDynamicValue().setHouseAvgPrice(NumberUtils.divide(first.getDynamicValue().getHousePrice(), first.getDynamicValue().getSaleArea(), 4));
					first.getDynamicValue().setParkingAvgPrice(NumberUtils.divide(first.getDynamicValue().getParkingPrice(), first.getDynamicValue().getParkingNum()==null?null:new BigDecimal(first.getDynamicValue().getParkingNum()), 4));
					first.getDifferenceValue().setHouseAvgPrice(NumberUtils.divide(first.getDifferenceValue().getHousePrice(), first.getDifferenceValue().getSaleArea(),4));
					first.getDifferenceValue().setParkingAvgPrice(NumberUtils.divide(first.getDifferenceValue().getParkingPrice(), first.getDifferenceValue().getParkingNum()==null?null:new BigDecimal(first.getDifferenceValue().getParkingNum()),4 ));
				
				}
				
				firstHalfYearValue.getBudgetValue().setHouseAvgPrice(NumberUtils.divide(firstHalfYearValue.getBudgetValue().getHousePrice(), firstHalfYearValue.getBudgetValue().getSaleArea(), 4));
				firstHalfYearValue.getBudgetValue().setParkingAvgPrice(NumberUtils.divide(firstHalfYearValue.getBudgetValue().getParkingPrice(), firstHalfYearValue.getBudgetValue().getParkingNum()==null?null:new BigDecimal(firstHalfYearValue.getBudgetValue().getParkingNum()), 4));
				firstHalfYearValue.getDynamicValue().setHouseAvgPrice(NumberUtils.divide(firstHalfYearValue.getDynamicValue().getHousePrice(), firstHalfYearValue.getDynamicValue().getSaleArea(), 4));
				firstHalfYearValue.getDynamicValue().setParkingAvgPrice(NumberUtils.divide(firstHalfYearValue.getDynamicValue().getParkingPrice(), firstHalfYearValue.getDynamicValue().getParkingNum()==null?null:new BigDecimal(firstHalfYearValue.getDynamicValue().getParkingNum()), 4));
				firstHalfYearValue.getDifferenceValue().setHouseAvgPrice(NumberUtils.divide(firstHalfYearValue.getDifferenceValue().getHousePrice(), firstHalfYearValue.getDifferenceValue().getSaleArea(),4));
				firstHalfYearValue.getDifferenceValue().setParkingAvgPrice(NumberUtils.divide(firstHalfYearValue.getDifferenceValue().getParkingPrice(), firstHalfYearValue.getDifferenceValue().getParkingNum()==null?null:new BigDecimal(firstHalfYearValue.getDifferenceValue().getParkingNum()),4 ));
				
				secondHalfYearValue.getBudgetValue().setHouseAvgPrice(NumberUtils.divide(secondHalfYearValue.getBudgetValue().getHousePrice(), secondHalfYearValue.getBudgetValue().getSaleArea(), 4));
				secondHalfYearValue.getBudgetValue().setParkingAvgPrice(NumberUtils.divide(secondHalfYearValue.getBudgetValue().getParkingPrice(), secondHalfYearValue.getBudgetValue().getParkingNum()==null?null:new BigDecimal(secondHalfYearValue.getBudgetValue().getParkingNum()), 4));
				secondHalfYearValue.getDynamicValue().setHouseAvgPrice(NumberUtils.divide(secondHalfYearValue.getDynamicValue().getHousePrice(), secondHalfYearValue.getDynamicValue().getSaleArea(), 4));
				secondHalfYearValue.getDynamicValue().setParkingAvgPrice(NumberUtils.divide(secondHalfYearValue.getDynamicValue().getParkingPrice(), secondHalfYearValue.getDynamicValue().getParkingNum()==null?null:new BigDecimal(secondHalfYearValue.getDynamicValue().getParkingNum()), 4));
				secondHalfYearValue.getDifferenceValue().setHouseAvgPrice(NumberUtils.divide(secondHalfYearValue.getDifferenceValue().getHousePrice(), secondHalfYearValue.getDifferenceValue().getSaleArea(),4));
				secondHalfYearValue.getDifferenceValue().setParkingAvgPrice(NumberUtils.divide(secondHalfYearValue.getDifferenceValue().getParkingPrice(), secondHalfYearValue.getDifferenceValue().getParkingNum()==null?null:new BigDecimal(secondHalfYearValue.getDifferenceValue().getParkingNum()),4 ));
				
				for(YearMonthComfirmVO second : secondMonthlyValue) {
					second.getBudgetValue().setHouseAvgPrice(NumberUtils.divide(second.getBudgetValue().getHousePrice(), second.getBudgetValue().getSaleArea(), 4));
					second.getBudgetValue().setParkingAvgPrice(NumberUtils.divide(second.getBudgetValue().getParkingPrice(), second.getBudgetValue().getParkingNum()==null?null:new BigDecimal(second.getBudgetValue().getParkingNum()), 4));
					second.getDynamicValue().setHouseAvgPrice(NumberUtils.divide(second.getDynamicValue().getHousePrice(), second.getDynamicValue().getSaleArea(), 4));
					second.getDynamicValue().setParkingAvgPrice(NumberUtils.divide(second.getDynamicValue().getParkingPrice(), second.getDynamicValue().getParkingNum()==null?null:new BigDecimal(second.getDynamicValue().getParkingNum()), 4));
					second.getDifferenceValue().setHouseAvgPrice(NumberUtils.divide(second.getDifferenceValue().getHousePrice(), second.getDifferenceValue().getSaleArea(),4));
					second.getDifferenceValue().setParkingAvgPrice(NumberUtils.divide(second.getDifferenceValue().getParkingPrice(), second.getDifferenceValue().getParkingNum()==null?null:new BigDecimal(second.getDifferenceValue().getParkingNum()),4 ));
				}
		}
	}
	
	private List<SupplyPlanVersionCompareVO> dataSort(List<SupplyPlanVersionCompareVO> dataList) {
		List<SupplyPlanVersionCompareVO> sortList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionCompareVO> stageList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionCompareVO> groupList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionCompareVO> productList = Collections.synchronizedList(new ArrayList<>());
		dataList.forEach(x->{
			String typeTemp = x.getType();
			if(typeTemp.equals(OrgTypeEunm.ORG_GROUP.getKey())){
		        groupList.add(x);
		    }else if(typeTemp.equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
		        productList.add(x);
		    }else if(typeTemp.equals(OrgTypeEunm.ORG_STAGE.getKey())) {
		    	stageList.add(x);
		    }else {
		    	sortList.add(x);
		    }
		});
		//分期
		if(CollectionUtils.isNotEmpty(stageList)){
			stageList.sort((a, b) -> {
                 String aCode = a.getCode();
                 String bCode = b.getCode();

                 if(StrUtils.isNotEmpty(aCode)) {
                	if(aCode.indexOf('.') >=0) {
                		aCode = aCode.substring(aCode.indexOf('.')+1, aCode.length());
                	}else {
                		aCode = "0";
                	}
                 }
                 
                 if(StrUtils.isNotEmpty(bCode)) {
                 	if(bCode.indexOf('.') >=0) {
                 		bCode = bCode.substring(bCode.indexOf('.')+1, bCode.length());
                 	}else {
                 		aCode = "0";
                 	}
                  }

                 return aCode == null ? 1 : bCode == null ? -1 : Integer.valueOf(aCode) - Integer.valueOf(bCode);
             });
			sortList.addAll(stageList);
         }
		//组团
		if(CollectionUtils.isNotEmpty(groupList)){
		     groupList.sort((a, b) -> {
		         String aName = a.getName();
		         String bName = b.getName();

		         String[] aStr = aName.split("组团");
		         String[] bStr = bName.split("组团");

		         if(aStr[0].equals(Constants.PARKING_NAME)) {
		             aStr[0] = Constants.GROUP_NUM;
		         }
		         if(bStr[0].equals(Constants.PARKING_NAME)){
		             bStr[0] = Constants.GROUP_NUM;
		         }

		         String aValue = NumberEnum.getKeyByValue(aStr[0]);
		         String bValue = NumberEnum.getKeyByValue(bStr[0]);

		         return aValue == null ? 1 : bValue == null ? -1 : Integer.valueOf(aValue) - Integer.valueOf(bValue);
		     });
		     sortList.addAll(groupList);
		 }
		//产品构成
		 if(CollectionUtils.isNotEmpty(productList)) {
		     productList.sort((a, b) -> {
		         String aCode = a.getCode();
		         String bCode = b.getCode();

		         return aCode == null ? 1 : bCode == null ? -1 : Integer.valueOf(aCode) - Integer.valueOf(bCode);
		     });
		     sortList.addAll(productList);
		 }
		return sortList;
	}
	
	
	public List<YearMonthComfirmVO> getMonthData(String year,int temp) {
		List<YearMonthComfirmVO> list = new ArrayList<>();
		if(temp == 1) {
			for(int i=1;i<=6;i++) {
				String m="";
				YearMonthComfirmVO vo = new YearMonthComfirmVO();
				if(i<10) {
					m="0"+i;
				}else {
					m=i+"";
				}
				vo.setYearMonth(year+"-"+m);
				list.add(vo);
			}
		}else {
			for(int i=7;i<=12;i++) {
				String m="";
				YearMonthComfirmVO vo = new YearMonthComfirmVO();
				if(i<10) {
					m="0"+i;
				}else {
					m=i+"";
				}
				vo.setYearMonth(year+"-"+m);
				list.add(vo);
			}
		}
		return list;
	}

	/**
	 * 
	 * @Description：添加项目层级
	 * @author：yyd
	 * @date：2020年2月15日 下午4:51:26
	 */
	private void addProjectData(List<SupplyPlanVersionCompareVO> resList,String projectId,String year) {
		SupplyPlanVersionCompareVO vo = new SupplyPlanVersionCompareVO();
		//获取项目信息
    	MdmProject project = projectMapper.selectByProjectId(projectId,IsDeleteEnum.NO.getKey());
		vo.setId(projectId);
		vo.setCode(project.getProjectCode());
		vo.setName(project.getProjectName());
		vo.setPid(Constants.ROOT_NODE_PID);
		vo.setType(OrgTypeEunm.ORG_PRODUCTF.getKey());
		
		List<YearMonthComfirmVO> firstMonthlyValue = getMonthData(year,1);
		vo.setFirstMonthlyValue(firstMonthlyValue);
		
		List<YearMonthComfirmVO> secondMonthlyValue = getMonthData(year,2);
		vo.setSecondMonthlyValue(secondMonthlyValue);
		
		resList.add(vo);
	}
	
	/**
	 * 
	 * @Description：数据汇总
	 * @author：yyd
	 * @date：2020年2月14日 下午2:56:28
	 */
	private void collectData(List<SupplyPlanVersionCompareVO> resList,String orgType) {
		if(CollectionUtils.isNotEmpty(resList)) {
			for(SupplyPlanVersionCompareVO vo : resList) {
				String type = vo.getType();
				if(type.equals(orgType)) {
					String id= vo.getId();
					List<SupplyPlanVersionCompareVO> childList = getChildDataList(id,resList);
					collectChildData(childList,vo);
				}
			}
		}
	}
	/**
	 * 
	 * @Description：子级数据汇总到父级
	 * @author：yyd
	 * @date：2020年2月15日 下午4:50:00
	 */
	private void collectChildData(List<SupplyPlanVersionCompareVO> childList,SupplyPlanVersionCompareVO parentObj) {
		if(CollectionUtils.isNotEmpty(childList)) {
			YearMonthComfirmVO parentYearValue = parentObj.getYearValue();
			List<YearMonthComfirmVO> parentFirstMonthlyValue = parentObj.getFirstMonthlyValue();
			YearMonthComfirmVO parentFirstHalfYearValue = parentObj.getFirstHalfYearValue();
			YearMonthComfirmVO parentSecondHalfYearValue = parentObj.getSecondHalfYearValue();
			List<YearMonthComfirmVO> parentSecondMonthlyValue = parentObj.getSecondMonthlyValue();
			for(SupplyPlanVersionCompareVO vo : childList) {
				YearMonthComfirmVO childYearValue = vo.getYearValue();
				List<YearMonthComfirmVO> childFirstMonthlyValue = vo.getFirstMonthlyValue();
				YearMonthComfirmVO childFirstHalfYearValue = vo.getFirstHalfYearValue();
				YearMonthComfirmVO childSecondHalfYearValue = vo.getSecondHalfYearValue();
				List<YearMonthComfirmVO> childSecondMonthlyValue = vo.getSecondMonthlyValue();
				
				yearDataCollect(parentYearValue, childYearValue);
				monthlyDataCollect(parentFirstMonthlyValue,childFirstMonthlyValue);
				yearDataCollect(parentFirstHalfYearValue, childFirstHalfYearValue);
				yearDataCollect(parentSecondHalfYearValue, childSecondHalfYearValue);
				monthlyDataCollect(parentSecondMonthlyValue,childSecondMonthlyValue);
			}
		}
	}
	/**
	 * 
	 * @Description：月度数据汇总处理
	 * @author：yyd
	 * @date：2020年2月15日 下午4:49:07
	 */
	private void monthlyDataCollect(List<YearMonthComfirmVO> parentValueList, List<YearMonthComfirmVO> childValueList) {
		for(YearMonthComfirmVO parentObj : parentValueList) {
			String pMonth = parentObj.getYearMonth();
			ComfirmBaseValueVO pBudgetValue = parentObj.getBudgetValue();
			ComfirmBaseValueVO pDynamicValue = parentObj.getDynamicValue();
			ComfirmBaseValueVO pDifferenceValue = parentObj.getDifferenceValue();
			for(YearMonthComfirmVO childObj : childValueList) {
				String cMonth = childObj.getYearMonth();
				ComfirmBaseValueVO cBudgetValue = childObj.getBudgetValue();
				ComfirmBaseValueVO cDynamicValue = childObj.getDynamicValue();
				ComfirmBaseValueVO cDifferenceValue = childObj.getDifferenceValue();
				if(pMonth.equals(cMonth)) {
					pBudgetValue.setRoomNum(NumberUtils.intADD(pBudgetValue.getRoomNum(),cBudgetValue.getRoomNum()));
					pBudgetValue.setParkingNum(NumberUtils.intADD(pBudgetValue.getParkingNum(),cBudgetValue.getParkingNum()));
					pBudgetValue.setSaleArea(NumberUtils.BigDecimalADD(4,pBudgetValue.getSaleArea(),cBudgetValue.getSaleArea()));
					pBudgetValue.setHousePrice(NumberUtils.BigDecimalADD(4,pBudgetValue.getHousePrice(),cBudgetValue.getHousePrice()));
					pBudgetValue.setParkingPrice(NumberUtils.BigDecimalADD(4,pBudgetValue.getParkingPrice(),cBudgetValue.getParkingPrice()));
					
					pDynamicValue.setRoomNum(NumberUtils.intADD(pDynamicValue.getRoomNum(),cDynamicValue.getRoomNum()));
					pDynamicValue.setParkingNum(NumberUtils.intADD(pDynamicValue.getParkingNum(),cDynamicValue.getParkingNum()));
					pDynamicValue.setSaleArea(NumberUtils.BigDecimalADD(4,pDynamicValue.getSaleArea(),cDynamicValue.getSaleArea()));
					pDynamicValue.setHousePrice(NumberUtils.BigDecimalADD(4,pDynamicValue.getHousePrice(),cDynamicValue.getHousePrice()));
					pDynamicValue.setParkingPrice(NumberUtils.BigDecimalADD(4,pDynamicValue.getParkingPrice(),cDynamicValue.getParkingPrice()));
					
					pDifferenceValue.setRoomNum(NumberUtils.intADD(pDifferenceValue.getRoomNum(),cDifferenceValue.getRoomNum()));
					pDifferenceValue.setParkingNum(NumberUtils.intADD(pDifferenceValue.getParkingNum(),cDifferenceValue.getParkingNum()));
					pDifferenceValue.setSaleArea(NumberUtils.BigDecimalADD(4,pDifferenceValue.getSaleArea(),cDifferenceValue.getSaleArea()));
					pDifferenceValue.setHousePrice(NumberUtils.BigDecimalADD(4,pDifferenceValue.getHousePrice(),cDifferenceValue.getHousePrice()));
					pDifferenceValue.setParkingPrice(NumberUtils.BigDecimalADD(4,pDifferenceValue.getParkingPrice(),cDifferenceValue.getParkingPrice()));
				}
			}
		}
	}
	
	/**
	 * 
	 * @Description：年度数据汇总处理
	 * @author：yyd
	 * @date：2020年2月15日 下午4:49:07
	 */
	private void yearDataCollect(YearMonthComfirmVO parentValue, YearMonthComfirmVO childValue) {
		parentValue.getBudgetValue().setRoomNum(NumberUtils.intADD(parentValue.getBudgetValue().getRoomNum(),childValue.getBudgetValue().getRoomNum()));
		parentValue.getBudgetValue().setParkingNum(NumberUtils.intADD(parentValue.getBudgetValue().getParkingNum(),childValue.getBudgetValue().getParkingNum()));
		parentValue.getBudgetValue().setSaleArea(NumberUtils.BigDecimalADD(4,parentValue.getBudgetValue().getSaleArea(),childValue.getBudgetValue().getSaleArea()));
		parentValue.getBudgetValue().setHousePrice(NumberUtils.BigDecimalADD(4,parentValue.getBudgetValue().getHousePrice(),childValue.getBudgetValue().getHousePrice()));
		parentValue.getBudgetValue().setParkingPrice(NumberUtils.BigDecimalADD(4,parentValue.getBudgetValue().getParkingPrice(),childValue.getBudgetValue().getParkingPrice()));
		
		parentValue.getDynamicValue().setRoomNum(NumberUtils.intADD(parentValue.getDynamicValue().getRoomNum(),childValue.getDynamicValue().getRoomNum()));
		parentValue.getDynamicValue().setParkingNum(NumberUtils.intADD(parentValue.getDynamicValue().getParkingNum(),childValue.getDynamicValue().getParkingNum()));
		parentValue.getDynamicValue().setSaleArea(NumberUtils.BigDecimalADD(4,parentValue.getDynamicValue().getSaleArea(),childValue.getDynamicValue().getSaleArea()));
		parentValue.getDynamicValue().setHousePrice(NumberUtils.BigDecimalADD(4,parentValue.getDynamicValue().getHousePrice(),childValue.getDynamicValue().getHousePrice()));
		parentValue.getDynamicValue().setParkingPrice(NumberUtils.BigDecimalADD(4,parentValue.getDynamicValue().getParkingPrice(),childValue.getDynamicValue().getParkingPrice()));
		
		parentValue.getDifferenceValue().setRoomNum(NumberUtils.intADD(parentValue.getDifferenceValue().getRoomNum(),childValue.getDifferenceValue().getRoomNum()));
		parentValue.getDifferenceValue().setParkingNum(NumberUtils.intADD(parentValue.getDifferenceValue().getParkingNum(),childValue.getDifferenceValue().getParkingNum()));
		parentValue.getDifferenceValue().setSaleArea(NumberUtils.BigDecimalADD(4,parentValue.getDifferenceValue().getSaleArea(),childValue.getDifferenceValue().getSaleArea()));
		parentValue.getDifferenceValue().setHousePrice(NumberUtils.BigDecimalADD(4,parentValue.getDifferenceValue().getHousePrice(),childValue.getDifferenceValue().getHousePrice()));
		parentValue.getDifferenceValue().setParkingPrice(NumberUtils.BigDecimalADD(4,parentValue.getDifferenceValue().getParkingPrice(),childValue.getDifferenceValue().getParkingPrice()));
	}
	
	/**
	 * 
	 * @Description：获取子级数据
	 * @author：yyd
	 * @date：2020年2月15日 下午4:49:07
	 */
	private List<SupplyPlanVersionCompareVO> getChildDataList(String id,List<SupplyPlanVersionCompareVO> resList) {
		List<SupplyPlanVersionCompareVO> list =  Collections.synchronizedList(new ArrayList<>());
		for(SupplyPlanVersionCompareVO vo : resList) {
			String pid = vo.getPid();
			if(pid.equals(id)) {
				list.add(vo);
			}
		}
		return list;
	}

	/**
	 * 
	 * @Description：月度对比 数据处理
	 * @author：yyd
	 * @date：2020年2月14日 下午2:56:28
	 */
	private void prepareMonthlyCompare(List<CompareDetailVO> budgetData,List<CompareDetailVO> dynamicData, String baseFullPathName,
			List<YearMonthComfirmVO> firstMonthlyValue, String month) {
		for(YearMonthComfirmVO yearMonthVo : firstMonthlyValue) {
			String monthTep = yearMonthVo.getYearMonth().split("-")[1];
			ComfirmBaseValueVO budgetValue = yearMonthVo.getBudgetValue();
			ComfirmBaseValueVO dynamicValue = yearMonthVo.getDynamicValue();
			ComfirmBaseValueVO differenceValue = yearMonthVo.getDifferenceValue();
			if(monthTep.equals(month)) {
				if(CollectionUtils.isNotEmpty(budgetData)) {
					for(CompareDetailVO budget : budgetData) {
						String fullPathName = budget.getOrgFullPathName();
						if(fullPathName.equals(baseFullPathName)) {
							budgetValue.setRoomNum(budget.getRoomNum());
							budgetValue.setParkingNum(budget.getParkingNum());
							budgetValue.setSaleArea(budget.getSaleArea());
							budgetValue.setHousePrice(budget.getHousePrice());
							budgetValue.setParkingPrice(budget.getParkingPrice());
							budgetValue.setHouseAvgPrice(NumberUtils.divide(budget.getHousePrice(),budget.getSaleArea(),2));
							budgetValue.setParkingAvgPrice(NumberUtils.divide(budget.getParkingPrice(),budget.getParkingNum()==null?null:new BigDecimal(budget.getParkingNum()),2));
						}
					}
				}
				if(CollectionUtils.isNotEmpty(dynamicData)) {
					for(CompareDetailVO dynamic : dynamicData) {
						String fullPathName = dynamic.getOrgFullPathName();
						if(fullPathName.equals(baseFullPathName)) {
							dynamicValue.setRoomNum(dynamic.getRoomNum());
							dynamicValue.setParkingNum(dynamic.getParkingNum());
							dynamicValue.setSaleArea(dynamic.getSaleArea());
							dynamicValue.setHousePrice(dynamic.getHousePrice());
							dynamicValue.setParkingPrice(dynamic.getParkingPrice());
							dynamicValue.setHouseAvgPrice(NumberUtils.divide(dynamic.getHousePrice(),dynamic.getSaleArea(),2));
							dynamicValue.setParkingAvgPrice(NumberUtils.divide(dynamic.getParkingPrice(),dynamic.getParkingNum()==null?null:new BigDecimal(dynamic.getParkingNum()),2));
						}
					}
				}
			}
			
			//差异
			Integer budgetRoomNum = budgetValue.getRoomNum();
			Integer budgetParkingNum = budgetValue.getParkingNum();
			BigDecimal budgetSaleArea = budgetValue.getSaleArea();
			BigDecimal budgetHousePrice = budgetValue.getHousePrice();
			BigDecimal budgetParkingPrice = budgetValue.getParkingPrice();
			BigDecimal budgetHouseAvgPrice= budgetValue.getHouseAvgPrice();
			BigDecimal budgetParkingAvgPrice = budgetValue.getParkingAvgPrice();
			
			Integer dynamicRoomNum = dynamicValue.getRoomNum();
			Integer dynamicParkingNum = dynamicValue.getParkingNum();
			BigDecimal dynamicSaleArea = dynamicValue.getSaleArea();
			BigDecimal dynamicHousePrice = dynamicValue.getHousePrice();
			BigDecimal dynamicParkingPrice = dynamicValue.getParkingPrice();
			BigDecimal dynamicHouseAvgPrice= dynamicValue.getHouseAvgPrice();
			BigDecimal dynamicParkingAvgPrice = dynamicValue.getParkingAvgPrice();
			
			//房源套数差异
	      	Integer roomNumDiff = NumberUtils.IntegerSubtract(dynamicRoomNum,budgetRoomNum);
	      	Integer parkingNumDiff = NumberUtils.IntegerSubtract(dynamicParkingNum,budgetParkingNum);
	      	BigDecimal areaDiff = NumberUtils.subtract(dynamicSaleArea,budgetSaleArea);
	      	BigDecimal housePriceDiff = NumberUtils.subtract(dynamicHousePrice,budgetHousePrice);
	      	BigDecimal parkingPriceDiff = NumberUtils.subtract(dynamicParkingPrice,budgetParkingPrice);
	      	BigDecimal houseAvgPriceDiff = NumberUtils.subtract(dynamicHouseAvgPrice,budgetHouseAvgPrice);
	      	BigDecimal parkingAvgPriceDiff = NumberUtils.subtract(dynamicParkingAvgPrice,budgetParkingAvgPrice);
		
	      	differenceValue.setRoomNum(roomNumDiff);
	      	differenceValue.setParkingNum(parkingNumDiff);
	      	differenceValue.setSaleArea(areaDiff);
	      	differenceValue.setHousePrice(housePriceDiff);
	      	differenceValue.setParkingPrice(parkingPriceDiff);
	      	differenceValue.setHouseAvgPrice(houseAvgPriceDiff);
	      	differenceValue.setParkingAvgPrice(parkingAvgPriceDiff);
		}
	}

	/**
	 * 
	 * @Description：年度对比 数据处理
	 * @author：yyd
	 * @date：2020年2月14日 下午2:56:28
	 */
	private void prepareYearCompareData(List<CompareDetailVO> budgetData,List<CompareDetailVO> dynamicData,
			String baseFullPathName,YearMonthComfirmVO yearValue) {
		if(CollectionUtils.isNotEmpty(budgetData)) {
			for(CompareDetailVO budget : budgetData) {
				String fullPathName = budget.getOrgFullPathName();
				if(fullPathName.equals(baseFullPathName)) {
					yearValue.getBudgetValue().setRoomNum(budget.getRoomNum());
					yearValue.getBudgetValue().setParkingNum(budget.getParkingNum());
					yearValue.getBudgetValue().setSaleArea(budget.getSaleArea());
					yearValue.getBudgetValue().setHousePrice(budget.getHousePrice());
					yearValue.getBudgetValue().setParkingPrice(budget.getParkingPrice());
					yearValue.getBudgetValue().setHouseAvgPrice(NumberUtils.divide(budget.getHousePrice(),budget.getSaleArea(),2));
					yearValue.getBudgetValue().setParkingAvgPrice(NumberUtils.divide(budget.getParkingPrice(),budget.getParkingNum()==null?null:new BigDecimal(budget.getParkingNum()),2));
					break;
				}
			}
		}
		if(CollectionUtils.isNotEmpty(dynamicData)) {
			for(CompareDetailVO dynamic : dynamicData) {
				String fullPathName = dynamic.getOrgFullPathName();
				if(fullPathName.equals(baseFullPathName)) {
					yearValue.getDynamicValue().setRoomNum(dynamic.getRoomNum());
					yearValue.getDynamicValue().setParkingNum(dynamic.getParkingNum());
					yearValue.getDynamicValue().setSaleArea(dynamic.getSaleArea());
					yearValue.getDynamicValue().setHousePrice(dynamic.getHousePrice());
					yearValue.getDynamicValue().setParkingPrice(dynamic.getParkingPrice());
					yearValue.getDynamicValue().setHouseAvgPrice(NumberUtils.divide(dynamic.getHousePrice(),dynamic.getSaleArea(),2));
					yearValue.getDynamicValue().setParkingAvgPrice(NumberUtils.divide(dynamic.getParkingPrice(),dynamic.getParkingNum()==null?null:new BigDecimal(dynamic.getParkingNum()),2));
					break;
				}
			}
		}
		//差异
		Integer budgetRoomNum = yearValue.getBudgetValue().getRoomNum();
		Integer budgetParkingNum = yearValue.getBudgetValue().getParkingNum();
		BigDecimal budgetSaleArea = yearValue.getBudgetValue().getSaleArea();
		BigDecimal budgetHousePrice = yearValue.getBudgetValue().getHousePrice();
		BigDecimal budgetParkingPrice = yearValue.getBudgetValue().getParkingPrice();
		BigDecimal budgetHouseAvgPrice= yearValue.getBudgetValue().getHouseAvgPrice();
		BigDecimal budgetParkingAvgPrice = yearValue.getBudgetValue().getParkingAvgPrice();
		
		Integer dynamicRoomNum = yearValue.getDynamicValue().getRoomNum();
		Integer dynamicParkingNum = yearValue.getDynamicValue().getParkingNum();
		BigDecimal dynamicSaleArea = yearValue.getDynamicValue().getSaleArea();
		BigDecimal dynamicHousePrice = yearValue.getDynamicValue().getHousePrice();
		BigDecimal dynamicParkingPrice = yearValue.getDynamicValue().getParkingPrice();
		BigDecimal dynamicHouseAvgPrice= yearValue.getDynamicValue().getHouseAvgPrice();
		BigDecimal dynamicParkingAvgPrice = yearValue.getDynamicValue().getParkingAvgPrice();
		
		//房源套数差异
      	Integer roomNumDiff = NumberUtils.IntegerSubtract(dynamicRoomNum,budgetRoomNum);
      	Integer parkingNumDiff = NumberUtils.IntegerSubtract(dynamicParkingNum,budgetParkingNum);
      	BigDecimal areaDiff = NumberUtils.subtract(dynamicSaleArea,budgetSaleArea);
      	BigDecimal housePriceDiff = NumberUtils.subtract(dynamicHousePrice,budgetHousePrice);
      	BigDecimal parkingPriceDiff = NumberUtils.subtract(dynamicParkingPrice,budgetParkingPrice);
      	BigDecimal houseAvgPriceDiff = NumberUtils.subtract(dynamicHouseAvgPrice,budgetHouseAvgPrice);
      	BigDecimal parkingAvgPriceDiff = NumberUtils.subtract(dynamicParkingAvgPrice,budgetParkingAvgPrice);
	
      	yearValue.getDifferenceValue().setRoomNum(roomNumDiff);
      	yearValue.getDifferenceValue().setParkingNum(parkingNumDiff);
      	yearValue.getDifferenceValue().setSaleArea(areaDiff);
      	yearValue.getDifferenceValue().setHousePrice(housePriceDiff);
      	yearValue.getDifferenceValue().setParkingPrice(parkingPriceDiff);
      	yearValue.getDifferenceValue().setHouseAvgPrice(houseAvgPriceDiff);
      	yearValue.getDifferenceValue().setParkingAvgPrice(parkingAvgPriceDiff);
	}

	public List<CompareDetailVO> handleData(String projectId,List<SupplyPlanVersionDetail> list,String deadline,String month,String halfKey,String versionType) {
		List<CompareDetailVO> resData = Collections.synchronizedList(new ArrayList<>());
		List<CompareDetailVO> productData = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(list)) {
			if(versionType.equals(VersionTypeEunm.BUDGET.getKey())) {
				String versionId = list.get(0).getVersionId();
				SupplyPlanVersion version = supplyPlanVersionMapper.selectOneByVersionId(versionId,IsDeleteEnum.NO.getKey());
				if(version != null) {
					String versionAttr = version.getVersionAttr();
					if(versionAttr.equals(VersionAttrEnum.BEFORE_WARPLAN.getKey())) {
						//处理投资版数据
						List<SupplyPlanVersionDetail> InvestmentDataList = handleInvestmentData(list);
						for(SupplyPlanVersionDetail detail : InvestmentDataList) {
							if(detail.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
								List<CompareDetailVO> productList = parpareInvestmentProductData(detail,deadline,month,halfKey);
								if(CollectionUtils.isNotEmpty(productList)) {
									productData.addAll(productList);
								}
							}else if(detail.getType().equals(OrgTypeEunm.ORG_GROUP.getKey())) {
								setGroupStageData(resData, detail,projectId,OrgTypeEunm.ORG_GROUP.getKey());
							}else if(detail.getType().equals(OrgTypeEunm.ORG_STAGE.getKey())) {
								setGroupStageData(resData, detail,projectId,OrgTypeEunm.ORG_STAGE.getKey());
							}
						}
					}else {
						for(SupplyPlanVersionDetail detail : list) {
							if(detail.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
								List<CompareDetailVO> productList = prapareProductData(list,detail,deadline,month,halfKey,versionType);
								if(CollectionUtils.isNotEmpty(productList)) {
									productData.addAll(productList);
								}
							}else if(detail.getType().equals(OrgTypeEunm.ORG_GROUP.getKey())) {
								setGroupStageData(resData, detail,projectId,OrgTypeEunm.ORG_GROUP.getKey());
							}else if(detail.getType().equals(OrgTypeEunm.ORG_STAGE.getKey())) {
								setGroupStageData(resData, detail,projectId,OrgTypeEunm.ORG_STAGE.getKey());
							}
						}
					}
				}
			}else {
				for(SupplyPlanVersionDetail detail : list) {
					if(detail.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
						List<CompareDetailVO> productList = prapareProductData(list,detail,deadline,month,halfKey,versionType);
						if(CollectionUtils.isNotEmpty(productList)) {
							productData.addAll(productList);
						}
					}else if(detail.getType().equals(OrgTypeEunm.ORG_GROUP.getKey())) {
						setGroupStageData(resData, detail,projectId,OrgTypeEunm.ORG_GROUP.getKey());
					}else if(detail.getType().equals(OrgTypeEunm.ORG_STAGE.getKey())) {
						setGroupStageData(resData, detail,projectId,OrgTypeEunm.ORG_STAGE.getKey());
					}
				}
			}
		}
		
		resData.addAll(productData);
		return resData;
	}
	
	/**
	 * 
	 * @Description：设置组团分期信息
	 * @author：yyd
	 * @date：2020年2月10日 下午4:00:39
	 */
	private void setGroupStageData(List<CompareDetailVO> resData, SupplyPlanVersionDetail detail,String projectId, String type) {
		CompareDetailVO vo = new CompareDetailVO();
		vo.setId(UUIDUtils.create());
		if(type.equals(OrgTypeEunm.ORG_STAGE.getKey())) {
			vo.setPid(projectId);
		}else {
			vo.setPid(detail.getPid());
		}
		vo.setOrgId(detail.getOrgId());
		vo.setOrgCode(detail.getOrgCode());
		vo.setOrgName(detail.getOrgName());
		vo.setType(detail.getType());
		vo.setOrgFullPath(detail.getOrgFullPath());
		vo.setOrgFullPathName(detail.getOrgFullPathName());
		resData.add(vo);
	}
	
	/**
	 * 
	 * @Description：重组产品构成层级数据
	 * @author：yyd
	 * @date：2020年2月10日 下午4:00:39
	 */
	public List<CompareDetailVO> prapareProductData(List<SupplyPlanVersionDetail> dataList,SupplyPlanVersionDetail detail,String deadline,String month,String halfKey,String versionType) {
		List<CompareDetailVO> productList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> list = Collections.synchronizedList(new ArrayList<>());
		String year = deadline.split("-")[0];
		if(StrUtils.isEmpty(month) && StrUtils.isEmpty(halfKey)) {
			//年度数据
			for(SupplyPlanVersionDetail obj : dataList) {
				if(obj.getPid().equals(detail.getId())) {
					String bussnessType =obj.getBusinessType();
					if(StrUtils.isNotEmpty(bussnessType) && isValid(bussnessType)) {
						if(versionType.equals(VersionTypeEunm.BUDGET.getKey())) {
							LocalDateTime planDate = obj.getSupplyDate();
							if(planDate != null && isSameYear(year,planDate)) {
								list.add(obj);
							}
						}else {
							LocalDateTime actualTime = obj.getSupplyTimeVirtual() == null ? obj.getSupplyDateActual() : obj.getSupplyTimeVirtual(); 
							if(actualTime != null && isSameYear(year,actualTime)) {
								list.add(obj);
								continue;
							}
							LocalDateTime planDate = obj.getSupplyDate();
							if(planDate != null && isSameYear(year,planDate)) {
								list.add(obj);
							}
						}
					}
				}
			}
		}else if(StrUtils.isEmpty(month) && StrUtils.isNotEmpty(halfKey)) {
			//半年度数据
			String begin ="";
			String end = "";
			if(halfKey.equals(firsthalfYearKey)) {
				begin = year+"-01";
				end = year+"-06";
			}else {
				begin = year+"-07";
				end = year+"-12";
			}
			LocalDateTime beginTime = LocalDateTimeUtils.toLocalDateTime(begin);
			LocalDateTime endTime = LocalDateTimeUtils.toLocalDateTime(end);
			for(SupplyPlanVersionDetail obj : dataList) {
				if(obj.getPid().equals(detail.getId())) {
					String bussnessType =obj.getBusinessType();
					if(StrUtils.isNotEmpty(bussnessType) && isValid(bussnessType)) {
						if(versionType.equals(VersionTypeEunm.BUDGET.getKey())) {
							LocalDateTime planDate = obj.getSupplyDate();
							if(planDate != null) {
								LocalDateTime supplyDateTime = LocalDateTimeUtils.toLocalDateTime(LocalDateTimeUtils.formatTime(planDate, "yyyy-MM"));
								if(isBetweenDate(beginTime,endTime,supplyDateTime)) {
									list.add(obj);
								}
							}
						}else {
							LocalDateTime actualTime = obj.getSupplyTimeVirtual() == null ? obj.getSupplyDateActual() : obj.getSupplyTimeVirtual(); 
							if(actualTime != null) {
								LocalDateTime actualDateTime = LocalDateTimeUtils.toLocalDateTime(LocalDateTimeUtils.formatTime(actualTime, "yyyy-MM"));
								if(isBetweenDate(beginTime,endTime,actualDateTime)) {
									list.add(obj);
									continue;
								}
							}
							
							LocalDateTime planDate = obj.getSupplyDate();
							if(planDate != null) {
								LocalDateTime supplyDateTime = LocalDateTimeUtils.toLocalDateTime(LocalDateTimeUtils.formatTime(planDate, "yyyy-MM"));
								if(isBetweenDate(beginTime,endTime,supplyDateTime)) {
									list.add(obj);
								}
							}
						}
					}
				}
			}
		}else {
			//月度数据
			String yearMonth = year+"-"+month;
			for(SupplyPlanVersionDetail obj : dataList) {
				if(obj.getPid().equals(detail.getId())) {
					String bussnessType =obj.getBusinessType();
					if(StrUtils.isNotEmpty(bussnessType) && isValid(bussnessType)) {
						if(versionType.equals(VersionTypeEunm.BUDGET.getKey())) {
							LocalDateTime planDate = obj.getSupplyDate();
							if(planDate != null) {
								String planTime = LocalDateTimeUtils.formatTime(planDate, "yyyy-MM");
								if(planTime.equals(yearMonth)) {
									list.add(obj);
								}
							}
						}else {
							LocalDateTime actualTime = obj.getSupplyTimeVirtual() == null ? obj.getSupplyDateActual() : obj.getSupplyTimeVirtual(); 
							if(actualTime != null) {
								String actualDateTime = LocalDateTimeUtils.formatTime(actualTime, "yyyy-MM");
								if(actualDateTime.equals(yearMonth)) {
									list.add(obj);
									continue;
								}
							}
							
							LocalDateTime planDate = obj.getSupplyDate();
							if(planDate != null) {
								String planTime = LocalDateTimeUtils.formatTime(planDate, "yyyy-MM");
								if(planTime.equals(yearMonth)) {
									list.add(obj);
								}
							}
						}
					}
				}
			}
		}
		
		if(CollectionUtils.isNotEmpty(list)) {
			for(SupplyPlanVersionDetail dto : list) {
				CompareDetailVO vo = new CompareDetailVO();
				vo.setId(UUIDUtils.create());
				vo.setType(OrgTypeEunm.ORG_PRODUCT.getKey());
				vo.setPid(detail.getPid());
				vo.setOrgId(detail.getOrgId());
				vo.setOrgCode(detail.getOrgCode());
				vo.setOrgName(detail.getOrgName());
				vo.setOrgFullPathName(detail.getOrgFullPathName()+"-"+dto.getBusinessTypeName()+"-"+dto.getFreeTypeName()+"-"+dto.getProTypeName());
				vo.setBusinessType(dto.getBusinessType());
				vo.setBusinessTypeName(dto.getBusinessTypeName());
				vo.setFreeType(dto.getFreeType());
				vo.setFreeTypeName(dto.getFreeTypeName());
				vo.setProType(dto.getProType());
				vo.setProTypeName(dto.getProTypeName());
				vo.setProProductCode(detail.getProProductCode());
				vo.setProProductType(detail.getProProductType());
				String proProductCode = detail.getProProductCode();
			    if(StrUtils.isNotEmpty(proProductCode) && proProductCode.equals("139")) {
				 vo.setIsParking(1);
			    }else {
				 vo.setIsParking(0);
			    }
				//取数处理
				handleBuildData(dto,vo,deadline,month,versionType,halfKey);
				productList.add(vo);
			}
		}
		//产品构成去重
		List<CompareDetailVO>  res = mergeProductData(productList,detail);
		return res;
	}
	
	private List<CompareDetailVO> mergeProductData(List<CompareDetailVO> tempList,SupplyPlanVersionDetail detail) {
		List<CompareDetailVO> resList = Collections.synchronizedList(new ArrayList<>());
		List<CompareDetailVO> lastList = Collections.synchronizedList(new ArrayList<>());
		for(CompareDetailVO de : tempList) {
			de.setTempOrgNames(de.getBusinessTypeName()+"-"+de.getFreeTypeName()+"-"+de.getProTypeName());
		}
		//去重
		resList = tempList.stream().collect(
	               Collectors.collectingAndThen(
	                       Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CompareDetailVO::getTempOrgNames))), ArrayList::new));
		
		if(tempList.size() == resList.size()) {
			return resList;
		}
		
		for(CompareDetailVO detailVo : resList) {
			CompareDetailVO vo = new CompareDetailVO();
			vo.setId(UUIDUtils.create());
			vo.setPid(detail.getPid());
			vo.setOrgId(detail.getOrgId());
			vo.setOrgCode(detail.getOrgCode());
			vo.setOrgName(detail.getOrgName());
			vo.setProProductCode(detail.getProProductCode());
			vo.setProProductType(detail.getProProductType());
			vo.setType(OrgTypeEunm.ORG_PRODUCT.getKey());
			vo.setOrgFullPathName(detail.getOrgFullPathName()+"-"+detailVo.getBusinessTypeName()+"-"+detailVo.getFreeTypeName()+"-"+detailVo.getProTypeName());
			String proProductCode = detail.getProProductCode();
		    if(StrUtils.isNotEmpty(proProductCode) && proProductCode.equals("139")) {
			 vo.setIsParking(1);
		    }else {
			 vo.setIsParking(0);
		    }
			vo.setBusinessType(detailVo.getBusinessType());
			vo.setBusinessTypeName(detailVo.getBusinessTypeName());
			vo.setFreeType(detailVo.getFreeType());
			vo.setFreeTypeName(detailVo.getFreeTypeName());
			vo.setProType(detailVo.getProType());
			vo.setProTypeName(detailVo.getProTypeName());
			lastList.add(vo);
		}
		
		//重新设值
		for(CompareDetailVO obj : lastList) {
			Integer isParking = obj.getIsParking();
			for(CompareDetailVO detailVo : tempList) {
				if(obj.getOrgFullPathName().equals(detailVo.getOrgFullPathName())) {
					obj.setRoomNum(NumberUtils.intADD(obj.getRoomNum(), detailVo.getRoomNum()));
					obj.setParkingNum(NumberUtils.intADD(obj.getParkingNum(), detailVo.getParkingNum()));
					if(isParking != null && isParking.intValue() == 0) {
						obj.setSaleArea(NumberUtils.BigDecimalADD(4, obj.getSaleArea(), detailVo.getSaleArea()));
					}
					obj.setHousePrice(NumberUtils.BigDecimalADD(4, obj.getHousePrice(), detailVo.getHousePrice()));
					obj.setParkingPrice(NumberUtils.BigDecimalADD(4, obj.getParkingPrice(), detailVo.getParkingPrice()));
				}
			}
		}
		return lastList;
	}

	private boolean isValid(String businessType) {
		return businessType.equals(SalyTypeEnum.SALABLE.getKey()) || businessType.equals(SalyTypeEnum.STAGE_SELF_SUSTAINMENT.getKey());
	}
	
	private boolean isSameYear(String year,LocalDateTime targetTime) {
		return StrUtils.isNotEmpty(year) && targetTime != null && targetTime.getYear() == Integer.parseInt(year);
	}
	
	private boolean isBetweenDate(LocalDateTime beginTime,LocalDateTime endTime,LocalDateTime targetTime) {
		return (targetTime.isAfter(beginTime) || targetTime.equals(beginTime)) && (targetTime.isBefore(endTime) || targetTime.equals(endTime));
	}
	
	private boolean isSameMonth(String yearMonth,String targetDate) {
		return yearMonth.equals(targetDate);
	}
	
	/**
	 * 
	 * @Description：处理产品构成子级数据
	 * @author：yyd
	 * @date：2020年2月12日 下午7:03:17
	 */
	private void handleBuildData(SupplyPlanVersionDetail dto,CompareDetailVO vo, String deadline,String month,String versionType,String halfKey) {
		String year = deadline.split("-")[0];
		int baseMonth = Integer.parseInt(deadline.split("-")[1]);
		int baseYearMonth = LocalDateTimeUtils.toIntYearMonth(Integer.valueOf(year), baseMonth);
		//半年度数据
		String begin ="";
		String end = "";
		if(halfKey.equals(firsthalfYearKey)) {
			begin = year+"-01";
			end = year+"-06";
		}else {
			begin = year+"-07";
			end = year+"-12";
		}
		LocalDateTime beginTime = LocalDateTimeUtils.toLocalDateTime(begin);
		LocalDateTime endTime = LocalDateTimeUtils.toLocalDateTime(end);
		
		LocalDateTime supplyDate = dto.getSupplyDate();
		if(supplyDate != null) {
			LocalDateTime supplyDateActual = dto.getSupplyTimeVirtual() == null ? dto.getSupplyDateActual() : dto.getSupplyTimeVirtual();
			int planSupplyDate = LocalDateTimeUtils.toIntYearMonth(supplyDate.getYear(), supplyDate.getMonthValue());
			int beginDate = LocalDateTimeUtils.toIntYearMonth(beginTime.getYear(), beginTime.getMonthValue());
			if(versionType.equals(VersionTypeEunm.BUDGET.getKey())) {
				//预算版-取数（计划合计）
				setPlanValue(dto,vo);
			}else {
				//动态版-年度取数（当前月份及之前取实际，当前月份以后取计划）
				if(StrUtils.isEmpty(month) && StrUtils.isEmpty(halfKey)) {
					if(isSameYear(year,supplyDate)) {
						if(supplyDateActual != null) {
							int actualSupplyDate = LocalDateTimeUtils.toIntYearMonth(supplyDateActual.getYear(), supplyDateActual.getMonthValue());
							if(isSameYear(year,supplyDateActual) && actualSupplyDate <= baseYearMonth) {
								setActualValue(dto,vo);
							}
						}else {
							if(planSupplyDate <= baseYearMonth) {
								setActualValue(dto,vo);
							}else {
								setPlanValue(dto,vo);
							}
						}
					}else {
						if(supplyDateActual != null) {
							int actualSupplyDate = LocalDateTimeUtils.toIntYearMonth(supplyDateActual.getYear(), supplyDateActual.getMonthValue());
							if(isSameYear(year,supplyDateActual) && actualSupplyDate <= baseYearMonth) {
								setActualValue(dto,vo);
							}else {
								setPlanValue(dto,vo);
							}
						}
					}
				}else if(StrUtils.isEmpty(month) && StrUtils.isNotEmpty(halfKey)){
					//动态版-上半年度取数（取实际）
					if(halfKey.equals(firsthalfYearKey)) {
						if(supplyDateActual != null) {
							LocalDateTime actualDateTime = LocalDateTimeUtils.toLocalDateTime(LocalDateTimeUtils.formatTime(supplyDateActual, "yyyy-MM"));
							if(isBetweenDate(beginTime, endTime,actualDateTime)) {
								setActualValue(dto,vo);
							}
						}
					}else {
						//动态版-下半年度取数（当前月份及之前取实际，当前月份以后取计划）
						if(planSupplyDate > baseYearMonth) {
							if(supplyDateActual != null) {
								int actualSupplyDate = LocalDateTimeUtils.toIntYearMonth(supplyDateActual.getYear(), supplyDateActual.getMonthValue());
								if(actualSupplyDate <= baseYearMonth && actualSupplyDate >= beginDate) {
									setActualValue(dto,vo);
								}else {
									setPlanValue(dto,vo);
								}
							}else {
								setPlanValue(dto,vo);
							}
						}else {
							if(supplyDateActual != null) {
								int actualSupplyDate = LocalDateTimeUtils.toIntYearMonth(supplyDateActual.getYear(), supplyDateActual.getMonthValue());
								if(actualSupplyDate <= baseYearMonth && actualSupplyDate >= beginDate) {
									setActualValue(dto,vo);
								}
							}
						}
					}
				}else {
					//动态版-月度取数（当前月份之前取实际，当前月份及以后取计划）
					//月度数据
					String yearMonth = year+"-"+month;
					int showYearMonth = LocalDateTimeUtils.toIntYearMonth(Integer.valueOf(year), Integer.valueOf(month));
					if(showYearMonth < baseYearMonth) {
						if(supplyDateActual != null) {
							String supplyTimeActual =  LocalDateTimeUtils.formatTime(supplyDateActual, "yyyy-MM");
							if(isSameMonth(yearMonth,supplyTimeActual)) {
								setActualValue(dto,vo);
							}
						}
					}else {
						if(supplyDate != null) {
							String supplyTime =  LocalDateTimeUtils.formatTime(supplyDate, "yyyy-MM");
							if(isSameMonth(yearMonth, supplyTime)) {
								setPlanValue(dto,vo);
							}
						}
					}
				}
			}
		}
	}
	
	/**
	 * 
	 * @Description：获取实际值
	 * @author：yyd
	 * @date：2020年2月14日 上午10:02:41
	 */
	private void setActualValue(SupplyPlanVersionDetail dto,CompareDetailVO vo) {
		vo.setRoomNum(dto.getRoomNumActual());
		vo.setParkingNum(dto.getParkingNumActual());
		if(vo.getIsParking() != null && vo.getIsParking().intValue() == 0) {
			vo.setSaleArea(dto.getAreaActual());
		}
		vo.setHousePrice(dto.getHouseCommodityValueActual());
		vo.setParkingPrice(dto.getNotCommodityValueActual());
	}
	
	/**
	 * 
	 * @Description：获取计划值
	 * @author：yyd
	 * @date：2020年2月14日 上午10:02:41
	 */
	private void setPlanValue(SupplyPlanVersionDetail dto,CompareDetailVO vo) {
		vo.setRoomNum(dto.getRoomNum());
		vo.setParkingNum(dto.getParkingNum());
		if(vo.getIsParking() != null && vo.getIsParking().intValue() == 0) {
			vo.setSaleArea(dto.getSaleArea());
		}
		vo.setHousePrice(dto.getHouseCommodityValue());
		vo.setParkingPrice(dto.getNotCommodityValue());
	}
	
	/**
	 * 
	 * @Description：项目数层级合并
	 * @author：yyd
	 * @date：2020年2月11日 下午4:47:25
	 */
	private List<CompareDetailVO> mergeData(List<List<CompareDetailVO>> compareList) {
		List<CompareDetailVO> resList = Collections.synchronizedList(new ArrayList<>());
		List<CompareDetailVO> stageList = Collections.synchronizedList(new ArrayList<>());
		List<CompareDetailVO> groupList = Collections.synchronizedList(new ArrayList<>());
		List<CompareDetailVO> productList = Collections.synchronizedList(new ArrayList<>());
		if(CollectionUtils.isNotEmpty(compareList)) {
			for(List<CompareDetailVO> list : compareList) {
				for(CompareDetailVO detail : list) {
					 if(detail.getType().equals(OrgTypeEunm.ORG_STAGE.getKey())) {
		    			 stageList.add(detail);
		    		 }else if(detail.getType().equals(OrgTypeEunm.ORG_GROUP.getKey())) {
		    			 groupList.add(detail);
		    		 }else if(detail.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
		    			 productList.add(detail);
		    		 }
				}
			}
		}
		
		 //分期去重
	   	 stageList = stageList.stream().collect(
	               Collectors.collectingAndThen(
	                       Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CompareDetailVO::getOrgName))), ArrayList::new));
	     //组团去重
	   	 groupList = groupList.stream().collect(
	   			 Collectors.collectingAndThen(
	   					 Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CompareDetailVO::getOrgName))), ArrayList::new));
	     //产品构成去重
	   	 productList = productList.stream().collect(
	   			 Collectors.collectingAndThen(
	   					 Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CompareDetailVO::getOrgFullPathName))), ArrayList::new));
	   	 //设置产品构成层级父级
		 for(CompareDetailVO p : productList) {
			 String fullPath = p.getOrgFullPathName();
			 for(CompareDetailVO g : groupList) {
				 String orgName = g.getOrgName();
				 if(fullPath.indexOf(orgName) != -1) {
					 p.setPid(g.getId());
					 break;
				 }
			 }
		 }
		 
		 //设置组团层级父级
		 for(CompareDetailVO g : groupList) {
			 String fullPath = g.getOrgFullPathName();
			 for(CompareDetailVO s : stageList) {
				 String orgName = s.getOrgName();
				 if(fullPath.indexOf(orgName) != -1) {
					 g.setPid(s.getId());
					 break;
				 }
			 }
		 }
		 
		 resList.addAll(stageList);
		 resList.addAll(groupList);
		 resList.addAll(productList);
		
		return resList;
	}
	
	
	/**
	 * 
	 * @Description：处理投资版数据(去除批次层级数据后重组)
	 * @date：2020年2月15日 下午5:26:04
	 */
	private List<SupplyPlanVersionDetail> handleInvestmentData(List<SupplyPlanVersionDetail> dataList) {
		//数据重组（将批次的子级放到组团下面并移除批次层级）
		List<SupplyPlanVersionDetail> uniqList = regroupData(dataList);
		return uniqList;
	}

	/**
	 * 
	 * @Description：数据重组（将批次的子级放到组团下面并移除批次层级）
	 * @author：yyd
	 * @date：2020年2月15日 下午5:25:48
	 */
	private List<SupplyPlanVersionDetail> regroupData(List<SupplyPlanVersionDetail> dataList) {
		List<SupplyPlanVersionDetail> resList = Collections.synchronizedList(new ArrayList<>());
		List<SupplyPlanVersionDetail> uniqList = Collections.synchronizedList(new ArrayList<>());
		Map<String, String> map = new HashMap<String, String>();
		for(SupplyPlanVersionDetail value : dataList) {
			String type = value.getType();
			if(type.equals(OrgTypeEunm.ORG_BATCH.getKey())) {
				String bId = value.getId();
				String bPid = value.getPid();
				map.put(bId, bPid);
			}
		}
		
		resList = dataList.stream().filter(e -> !OrgTypeEunm.ORG_BATCH.getKey().equals(e.getType())).collect(Collectors.toList());
		
		for(SupplyPlanVersionDetail value : resList) {
			String pid = value.getPid();
			for(Map.Entry<String, String> entry : map.entrySet()){
	            if(entry.getKey().equals(pid)) {
	            	value.setPid(entry.getValue());
	            }
	        }
		}
		
		setSupplyOrgFullpath(resList,Constants.ROOT_NODE_PID);
		
		for(SupplyPlanVersionDetail value : resList) {
			if(value.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
				value.setOrgFullPathName(value.getOrgFullPathName()+"/"+value.getBusinessTypeName()+"/"+value.getFreeTypeName()+"/"+value.getProTypeName());
			}
		}
		
		//去重
		uniqList = resList.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SupplyPlanVersionDetail::getOrgFullPathName))), ArrayList::new));
		
		for(SupplyPlanVersionDetail price : uniqList) {
			prepareData(dataList, price);
		}
		
		return uniqList;
	}
	
	private void prepareData(List<SupplyPlanVersionDetail> dataList, SupplyPlanVersionDetail detail) {
		String orgNames = detail.getOrgFullPathName();
		for(SupplyPlanVersionDetail value : dataList) {
			if(orgNames.equals(value.getOrgFullPathName())) {
				if(detail.getId().equals(value.getId())) {
					continue;
				}
				detail.setRoomNum(NumberUtils.intADD(detail.getRoomNum(), value.getRoomNum()));
				detail.setParkingNum(NumberUtils.intADD(detail.getParkingNum(), value.getParkingNum()));
				detail.setSaleArea(NumberUtils.BigDecimalADD(4, detail.getSaleArea(), value.getSaleArea()));
				detail.setCommodityValue(NumberUtils.BigDecimalADD(4, detail.getCommodityValue(), value.getCommodityValue()));
				detail.setHouseCommodityValue(NumberUtils.BigDecimalADD(4, detail.getHouseCommodityValue(), value.getHouseCommodityValue()));
				detail.setNotCommodityValue(NumberUtils.BigDecimalADD(4, detail.getNotCommodityValue(), value.getNotCommodityValue()));
				
				detail.setRoomNumActual(NumberUtils.intADD(detail.getRoomNumActual(), value.getRoomNumActual()));
				detail.setParkingNumActual(NumberUtils.intADD(detail.getParkingNumActual(), value.getParkingNumActual()));
				detail.setAreaActual(NumberUtils.BigDecimalADD(4, detail.getAreaActual(), value.getAreaActual()));
				detail.setCommodityValueActual(NumberUtils.BigDecimalADD(4, detail.getCommodityValueActual(), value.getCommodityValueActual()));
				detail.setHouseCommodityValueActual(NumberUtils.BigDecimalADD(4, detail.getHouseCommodityValueActual(), value.getHouseCommodityValueActual()));
				detail.setNotCommodityValueActual(NumberUtils.BigDecimalADD(4, detail.getNotCommodityValueActual(), value.getNotCommodityValueActual()));
			}
		}
	}
	
	/**
	 * 
	 * 方法描述：设置供货计划详情全路劲
	 * 创建人：yyd
	 * 创建时间：2019年11月11日 下午7:52:24
	 */
	private List<SupplyPlanVersionDetail> setSupplyOrgFullpath(List<SupplyPlanVersionDetail> supplyPlanValueOrgList, String pid) {
		String fullPath ="";
		String fullPathName = "";
		for(SupplyPlanVersionDetail org : supplyPlanValueOrgList) {
			if(org.getId().equals(pid)) {
				fullPath= org.getOrgFullPath();
				fullPathName = org.getOrgFullPathName();
			}
		}
		
		for(SupplyPlanVersionDetail org : supplyPlanValueOrgList) {
			if(org.getPid().equals(pid)) {
				if(org.getType().equals(OrgTypeEunm.ORG_PRODUCT.getKey())) {
					org.setOrgFullPath(fullPath+"/"+org.getProProductCode()+"/"+org.getOrgCode());
					org.setOrgFullPathName(fullPathName+"/"+org.getProProductType()+"/"+org.getOrgName());
				}else {
					org.setOrgFullPath(fullPath+"/"+org.getOrgCode());
					org.setOrgFullPathName(fullPathName+"/"+org.getOrgName());
				}
				setSupplyOrgFullpath(supplyPlanValueOrgList,org.getId());
			}
		}
		
		return supplyPlanValueOrgList;
	}
	
	
	
	/**
	 * 
	 * @Description：预算版查询参数设置
	 * @author：yyd
	 * @date：2020年2月10日 上午11:39:42
	 */
	private BudgetVersionDto prepareBudgetParameters(String projectFid, String year,String versionIdentify) {
		BudgetVersionDto budgetVersionDto =  new BudgetVersionDto();
		budgetVersionDto.setIsDelete(IsDeleteEnum.NO.getKey());
		budgetVersionDto.setVersionType(VersionTypeEunm.BUDGET.getKey());
		budgetVersionDto.setBudgetYear(year);
		budgetVersionDto.setVersionIdentify(versionIdentify);
		budgetVersionDto.setProjectFid(projectFid);
		return budgetVersionDto;
	}
	
	/**
	 * 
	 * @Description：预算版查询参数设置
	 * @author：yyd
	 * @date：2020年2月10日 上午11:39:42
	 */
	private DynamicVersionDto prepareDynamicParameters(String projectFid, String yearMonth) {
		DynamicVersionDto dynamicVersionDto =  new DynamicVersionDto();
		dynamicVersionDto.setIsDelete(IsDeleteEnum.NO.getKey());
		dynamicVersionDto.setVersionType(VersionTypeEunm.DYNAMIC.getKey());
		dynamicVersionDto.setYearMonth(yearMonth);
		dynamicVersionDto.setProjectFid(projectFid);
		return dynamicVersionDto;
	}
	
	//TODO:方式二===================================================================================================
	public List<CompareDetailVO> parpareInvestmentProductData(SupplyPlanVersionDetail detail,
			String deadline,String month,String halfKey) {
		
		List<CompareDetailVO> productList = Collections.synchronizedList(new ArrayList<>());
		String deadlineYear = deadline.split("-")[0];
		LocalDateTime supplyDate = detail.getSupplyDate();
		//年度
		if(supplyDate != null) {
			if(StrUtils.isEmpty(month)) {
				String year = String.valueOf(supplyDate.getYear());
				if(year.equals(deadlineYear)) {
					CompareDetailVO vo = initCompareDeatil(detail);
					getPlanValue(detail,vo);
					productList.add(vo);
				}
			}else if(StrUtils.isEmpty(month) && StrUtils.isNotEmpty(halfKey)) {
				int supplyDateMonth = supplyDate.getMonthValue();
				if(halfKey.equals(firsthalfYearKey)) {
					if(supplyDateMonth>= 1 && supplyDateMonth <=6) {
						CompareDetailVO vo = initCompareDeatil(detail);
						getPlanValue(detail,vo);
						productList.add(vo);
					}
				}else {
					if(supplyDateMonth>= 7 && supplyDateMonth <=12) {
						CompareDetailVO vo = initCompareDeatil(detail);
						getPlanValue(detail,vo);
						productList.add(vo);
					}
				}
			}else {
				String supplyDateMonth = LocalDateTimeUtils.formatTime(supplyDate, "yyyy-MM");
				String yearMonth = deadlineYear+"-"+month;
				if(supplyDateMonth.equals(yearMonth)) {
					CompareDetailVO vo = initCompareDeatil(detail);
					getPlanValue(detail,vo);
					productList.add(vo);
				}
			}
		}
		return productList;
	}
	
	private CompareDetailVO initCompareDeatil(SupplyPlanVersionDetail detail) {
		CompareDetailVO vo = new CompareDetailVO();
		vo.setId(UUIDUtils.create());
		vo.setPid(detail.getPid());
		vo.setOrgId(detail.getOrgId());
		vo.setOrgCode(detail.getOrgCode());
		vo.setOrgName(detail.getOrgName());
		vo.setProProductCode(detail.getProProductCode());
		vo.setProProductType(detail.getProProductType());
		vo.setType(OrgTypeEunm.ORG_PRODUCT.getKey());
		vo.setOrgFullPath(detail.getOrgFullPath());
		vo.setOrgFullPathName(detail.getOrgFullPathName()+"/"+detail.getBusinessTypeName()+"/"+detail.getFreeTypeName()+"/"+detail.getProTypeName());
		
		String proProductCode = detail.getProProductCode();
		    if(StrUtils.isNotEmpty(proProductCode) && proProductCode.equals("139")) {
			 vo.setIsParking(1);
		    }else {
			 vo.setIsParking(0);
		    }
		vo.setBusinessType(detail.getBusinessType());
		vo.setBusinessTypeName(detail.getBusinessTypeName());
		vo.setFreeType(detail.getFreeType());
		vo.setFreeTypeName(detail.getFreeTypeName());
		vo.setProType(detail.getProType());
		vo.setProTypeName(detail.getProTypeName());
		return vo;
	}
	
	private void getPlanValue(SupplyPlanVersionDetail dto,CompareDetailVO vo) {
		vo.setRoomNum(dto.getRoomNum());
		vo.setParkingNum(dto.getParkingNum());
		if(vo.getIsParking() != null && vo.getIsParking().intValue() == 0) {
			vo.setSaleArea(dto.getSaleArea());
		}
		vo.setHousePrice(dto.getHouseCommodityValue());
		vo.setParkingPrice(dto.getNotCommodityValue());
	}

}
